package org.cgs.web.beans;

import java.util.ArrayList;
import java.util.List;

public final class Assignment implements Comparable<Assignment>
{
	// The attributes of an Assignment object
	private final List<Student> studentList;
	private final School school;
	private final String time1;
	private final String time2;
	//
	private boolean vehicleConstraintSatisfied;
	private boolean teachingExperienceConstraintSatisfied;
	private boolean subjectKnowledgeConstraintSatisfied;

	public Assignment(List<Student> stu, School sch, String tim1, String tim2)
	{
		studentList = stu;
		school = sch;
		time1 = tim1;
		time2 = tim2;

		// Update the constraints for this assignment
		updateConstraints();
	} // End constructor

	public Assignment(Student stu, School sch, String tim1, String tim2)
	{
		studentList = new ArrayList<Student>();
		studentList.add(stu);

		school = sch;
		time1 = tim1;
		time2 = tim2;

		// Update the constraints for this assignment
		updateConstraints();
	} // End constructor
	
	//
	// Get/Set methods
	//
	
	public School getSchool()
	{
		return school;
	} // End method

	public List<Student> getStudents()
	{
		return studentList;
	} // End method

	public String getTime1()
	{
		return time1;
	} // End method

	public String getTime2()
	{
		return time2;
	} // End method
	
	public boolean isSubjectKnowledgeConstraintSatisfied()
	{
		return subjectKnowledgeConstraintSatisfied;
	} // End method

	public boolean isTeachingExperienceConstraintSatisfied()
	{
		return teachingExperienceConstraintSatisfied;
	} // End method

	public boolean isVehicleConstraintSatisfied()
	{
		return vehicleConstraintSatisfied;
	} // End method

	//
	// Override methods
	//
	
	@Override
	public Assignment clone()
	{
		try
		{
			super.clone();
		} // End try block
		catch (CloneNotSupportedException e)
		{
			// Ignore it
		} // End catch block

		return new Assignment(studentList, school, time1, time2);
	} // End method
	
	@Override
	public boolean equals(Object obj)
	{
		if (obj instanceof Assignment)
		{
			Assignment ass = (Assignment) obj;
			return time1.equalsIgnoreCase(ass.time1) && time2.equalsIgnoreCase(ass.time2);
		} // End if

		return false;
	} // End method

	@Override
	public int hashCode()
	{
		return time1.hashCode();
	} // End method
	
	@Override
	public String toString()
	{
		return "Assignment: " + time1 + "-" + time2 + '\n' + school.toString() + "-" + studentList.toString();
	} // End method
	
	public int compareTo(Assignment ass)
	{
		return time1.compareTo(ass.time1);
	} // End method
	
	
	public void addStudent(Student stu)
	{
		// Add the student to the list
		studentList.add(stu);

		// Update the constraints that this student adds to the assignment
		updateConstraints();
	} // End method

	//
	// Operational methods
	//

	/**
	 * Get the number of students that have been assigned to a school so far
	 * 
	 * @return The number of students that have been assigned to a school so far
	 */
	public int getNumberOfAssignedStudents()
	{
		return studentList.size();
	} // End method

	/**
	 * The number of students the school requested for the session
	 * 
	 * @return The number of students the school requested for the session
	 */
	public int getNumberOfStudentsRequested()
	{
		return school.getNumStudents();
	} // End method

	/**
	 * Get the number of students that have access to a vehicle
	 * 
	 * @return The number of students that have a vehicle
	 */
	public int getNumberOfStudentsWithVehicles()
	{
		int numStudentsWithVehicles = 0;

		for (Student s : studentList)
		{
			if (s.isHasVehicle())
			{
				numStudentsWithVehicles++;
			} // End if
		} // End for loop

		return numStudentsWithVehicles;
	} // End method

	public boolean studentHasVehicle()
	{
		for (Student s : studentList)
		{
			if (s.isHasVehicle())
			{
				return true;
			} // End if
		} // End for loop

		return false;
	} // End method

	private void updateConstraints()
	{
		if (school == null)
		{
			return;
		} // End if

		// Reset all constraints to false
		vehicleConstraintSatisfied = false;
		subjectKnowledgeConstraintSatisfied = false;
		teachingExperienceConstraintSatisfied = false;

		for (Student stu : studentList)
		{
			if ((school.isFarSchool() && stu.isHasVehicle()) || !school.isFarSchool())
			{
				vehicleConstraintSatisfied = true;
			} // End if

			if (stu.isHasSubjectKnowledge())
			{
				subjectKnowledgeConstraintSatisfied = true;
			} // End if

			if (stu.isHasTeachingExperience())
			{
				teachingExperienceConstraintSatisfied = true;
			} // End if
		} // End for loop
	} // End method
} // End class
